home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ETO Development Tools 4
/
ETO Development Tools 4.iso
/
Tools - Objects
/
Macintosh Programmer’s Workshop
/
MPW QR4
/
SADE 1.3b1
/
SadeStartup
< prev
next >
Wrap
Text File
|
1991-04-25
|
27KB
|
833 lines
##########################################################################################
# Symbolic Application Debugging Environment 1.3
#
# Copyright Apple Computer, Inc. 1987-1991
# All rights reserved.
#
##########################################################################################
#
# SADEStartup -- default OnEntry mechanism and support for source level debugging.
#
#
# The following variables are used by the OnEntry and source & variable display mechanism.
#
define __SourceDbg__ := 1 # controls source vs. low-level debugging
define __MaxWatchVars__ := 10 # maximum number of watched variables
define __NumWatchVars__ := 0 # current number of watch variables
define __WatchVar__[__MaxWatchVars__] # names of variables to watch
define __MaxBreakifs__ := 10 # maximum number of conditional breaks
define __BreakifAddr__[__MaxBreakifs__] # conditional break addresses
define __BreakifCond__[__MaxBreakifs__] # conditional break conditions
define __i__
for __i__ := 1 to __MaxBreakifs__ do
__BreakifAddr__[__i__] := 0
end
define SADEDir := WorksheetWindow
for __i__ := length(SADEDir) downto 1 do
if copy(SADEDir, __i__, 1) = ':' then
SADEDir := copy(SADEDir, 1, __i__)
leave
end
end
undefine __i__
# This sets the size of new windows [top, left, bottom, right]
WindowSize New 0, 0, 200, 200
#
# You may change the default values below to change how source level displays work.
#
define __SourceInFront__ := 1 # controls whether source will be brought up as frontmost window
# Set this if you want an alert on hitting a breakpoint.
define Breakalert := 0 # controls breakpoint alert
# Set __WantStackWindow__ to 1 if you want a live Stack window which updates every
# time you step. Since this slows things down, you may prefer to leave it 0 and just
# ask for a snapshot of the stack when you need to.
define __WantStackWindow__ := 0 # controls stack display
proc ToggleWantStackWindow
if __WantStackWindow__ = 0 then
__WantStackWindow__ := 1
open concat(SADEDir, "Stack")
addmenu 'Variables' '!Live Stack Window' 'ToggleWantStackWindow' # '' is control-r (a checkmark)
else
__WantStackWindow__ := 0
save concat(SADEDir, "Stack")
close concat(SADEDir, "Stack")
addmenu 'Variables' 'Live Stack Window' 'ToggleWantStackWindow'
end
end
proc __Fail__(__ErrorString__)
Alert __ErrorString__
redirect pop
Abort
end
# Set __WantRegisterWindow__ to 1 if you want a live Registers window which updates every
# time you step. Since this slows things down, you may prefer to leave it 0 and just
# ask for a snapshot of the registers when you need to.
define __WantRegisterWindow__ := 0 # controls register display
proc ToggleWantRegisterWindow
if __WantRegisterWindow__ = 0 then
__WantRegisterWindow__ := 1
open concat(SADEDir, "Registers")
addmenu 'Variables' '!Live Register Window' 'ToggleWantRegisterWindow' # '' is control-r (a checkmark)
else
__WantRegisterWindow__ := 0
close concat(SADEDir, "Registers")
addmenu 'Variables' 'Live Register Window' 'ToggleWantRegisterWindow'
end
end
#
# You can set the Safety variable to 1 if you want SADE to be more careful
# when stepping and breaking. The default setting slightly increases the
# possibility of SADE crashing because of a memory stomper in user code,
# but makes stepping and breaking ten times faster.
#
Safety := 0
#
# By default, BreakifNoSource is false. This allows SADE to step
# through routines like LMODT and UDIVT. It also lets SADE step
# through Object Pascal and MacApp method dispatch code. However,
# if you have enabled symbolics for only a small portion of your
# code and do a step into, it will appear that SADE has hung when
# it is really single stepping through zillions of instructions.
# The default setting of 0 supports MacApp and avoids mystery
# breaks in LMODT. See the "SADE New User WorkSheet" for details.
BreakifNoSource := 0
proc ToggleBreakifNoSource
if BreakifNoSource = 0 then
BreakifNoSource := 1
addmenu 'SourceCmds' '!Break if No Source' 'ToggleBreakifNoSource' # '' is control-r (a checkmark)
else
BreakifNoSource := 0
addmenu 'SourceCmds' 'Break if No Source' 'ToggleBreakifNoSource'
end
end
#
# By default, __StopBeforeStatic__ is 0. This makes SADE step to
# main.(0) when an application is launched. If you set it to 1, SADE
# will give you control before any code in the app is run. You can then
# place breakpoints at your static constructors before you proceed.
#
define __StopBeforeStatic__ := 0
proc ToggleStopBeforeStatic
if __StopBeforeStatic__ = 0 then
__StopBeforeStatic__ := 1
addmenu 'File' '!Stop Before Constructor' 'ToggleStopBeforeStatic'
else
__StopBeforeStatic__ := 0
addmenu 'File' 'Stop Before Constructor' 'ToggleStopBeforeStatic' # '' is control-r (a checkmark)
end
end
# This macro is used by scripts below to check if there is a valid target.
macro CheckNullTarget 'if processId = 0 then;alert "No process targeted.";abort;end'
# This macro is used to check if the target is running.
macro CheckRunningTarget 'if TargetRunning then;alert "Target is running.";abort;end'
macro CheckNullOrRunningTarget 'CheckNullTarget;CheckRunningTarget'
# This macro is used to see if we are at a "LINK A6, $xxxx" instruction
# (local variables are not valid until after the instruction has executed).
macro PCIsAtLinkA6 '^ΔWord(ΔPC)^ = $4E56' # LINK opword = $4E56
# If we haven't executed the LINK instruction, print a warning.
proc CheckValidLocalVars
if PCIsAtLinkA6 then
printf "Note: Parameters and local variables\naren't valid yet at this statement.\n"
end
end
# Return true if the 1st character of __theStr__ is in [A-Z,a-z,_]
func IsAlpha(__theStr__)
define __theChar__ := copy(__theStr__, 1, 1)
if (__theChar__ >= 'a') and (__theChar__ <= 'z') then
return 1
end
if (__theChar__ >= 'A') and (__theChar__ <= 'Z') then
return 1
end
if (__theChar__ = '_') then
return 1
end
return 0
end
# Add a backquote to the selected name to evaluate it as a program variable.
func BackquotedSelection(__theSelection__)
if copy(__theSelection__, 1, 1) = '`' then
return __theSelection__
end
if IsAlpha(__theSelection__)
return concat('`', __theSelection__)
end
return __theSelection__
end
# Print a variable's name and value, with linebreaks as necessary.
proc PrettyPrintValue(__theSelection__)
if Length(__theSelection__) = 0 then
Alert "Selection is zero-length."
return
end
__theSelection__ := BackquotedSelection(__theSelection__)
define EvaledVar := Eval(__theSelection__, '???')
if TypeOf(EvaledVar) = 'PString' then
if EvaledVar = '???' then
printf "%s = Undefined/Out of scope\n", __theSelection__
return
elseif copy(EvaledVar, 1, 21) = '### Eval syntax error' then
printf "%s = Expression syntax error", __theSelection__
return
end
end
if Length(__theSelection__) > 20 then
printf "%s =\n%t\n", __theSelection__, EvaledVar
else
printf "%s = %t\n", __theSelection__, EvaledVar
end
end
# Print a variable's name and its value in hex, with linebreaks as necessary.
proc PrettyPrintValueInHex(__theSelection__)
if Length(__theSelection__) = 0 then
Alert "Selection is zero-length."
return
end
__theSelection__ := BackquotedSelection(__theSelection__)
define EvaledVar := Eval(__theSelection__, '???')
if TypeOf(EvaledVar) = 'PString' then
if EvaledVar = '???' then
printf "%s = Undefined/Out of scope\n", __theSelection__
return
elseif copy(EvaledVar, 1, 21) = '### Eval syntax error' then
printf "%s = Expression syntax error", __theSelection__
return
else
printf "Printing strings as hex values does not work well.\n"
end
end
if SizeOf(EvaledVar) > 4 then
printf "Printing of non-integral objects as hex values does not work well.\n"
printf "%s =\n$%X\n", __theSelection__, EvaledVar
else
printf "%s = $%X\n", __theSelection__, EvaledVar
end
end
# Display the watch variables.
proc DisplayWatchVars
define __i__
open behind concat(SADEDir, "Variable Watch")
redirect concat(SADEDir, "Variable Watch")
CheckValidLocalVars
for __i__ := 1 to __NumWatchVars__ do
PrettyPrintValue(__WatchVar__[__i__])
end
redirect pop
end
#
# Register display -- the Registers and DisplayRegs procs
#
proc Registers
printf "D0: $%.8X\nD1: $%.8X\nD2: $%.8X\nD3: $%.8X\nD4: $%.8X\nD5: $%.8X\nD6: $%.8X\nD7: $%.8X\n\n", ΔD0, ΔD1, ΔD2, ΔD3, ΔD4, ΔD5, ΔD6, ΔD7
printf "A0: $%.8X\nA1: $%.8X\nA2: $%.8X\nA3: $%.8X\nA4: $%.8X\nA5: $%.8X\nA6: $%.8X\nA7: $%.8X\n\n", ΔA0, ΔA1, ΔA2, ΔA3, ΔA4, ΔA5, ΔA6, ΔA7
printf "PC: $%.8X\n\n", ΔPC
printf "\tXNZVC\n"
printf "CCR\t%.5b\n", ΔCCR & $1F
end
proc DisplayRegs
CheckNullTarget
if TargetRunning then
alert "The target is running. You must halt it to see its registers."
abort
end
open concat(SADEDir, "Registers")
SizeWindow To 160, 295 concat(SADEDir, "Registers")
redirect concat(SADEDir, "Registers")
Registers
redirect pop
end
#
# Stack display -- the DoStack and DisplayStack procs
#
proc DoStack
if PCIsAtLinkA6 then
printf "Stack isn't valid yet at this statement.\n"
else
stack
end
end
proc DisplayStack
CheckNullTarget
if TargetRunning then
alert "The target is running. You must halt it to see its stack."
abort
end
open concat(SADEDir, "Stack")
redirect concat(SADEDir, "Stack")
DoStack
redirect pop
end
#••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
#
# Entry handling -- the StandardEntry proc
#
macro kSEprocessLoaded '65'
macro kSETrace '51'
macro kSEAddressBreak '58'
macro kSESADEKeyInterrupt '55'
macro kSEprocessHalted '8194'
func GetErrorString()
define __errCause__ := ''
if Exception = kSETrace then
__errCause__ := "Instruction trace"
elseif Exception = kSEAddressBreak then
__errCause__ := "Address Break encountered"
elseif Exception = 50 then
__errCause__ := "Trap Break encountered"
elseif (Exception = kSESADEKeyInterrupt) | (Exception = 13) then
__errCause__ := "Program interrupted"
elseif (Exception = kSEprocessHalted) then
__errCause__ := "process Halted"
elseif Exception = 1 then
__errCause__ := "Bus Error"
elseif Exception = 2 then
__errCause__ := "Address Error"
elseif Exception = 3 then
__errCause__ := "Illegal instruction encountered"
elseif Exception = 4 then
__errCause__ := "Divide by zero encountered"
elseif Exception = 5 then
__errCause__ := "CHK exception (array index out of range) encountered"
elseif Exception = 6 then
__errCause__ := "TRAPV or TRAPcc instruction encountered"
elseif Exception = 7 then
__errCause__ := "Privilege Violation"
elseif Exception = 63 then
__errCause__ := "Internal non-fatal error! You may be able to proceed..."
elseif Exception = 64 then
__errCause__ := "Internal fatal error! Please kill the target process!"
elseif Exception = kSEprocessLoaded then
__errCause__ := "Initial program break encountered"
elseif Exception = -490 then
__errCause__ := "User Break encountered"
elseif Exception = -491 then
__errCause__ := concat ("∂"", ^PString(ΔSP^)^, "∂"")
ΔSP := ΔSP+4;
elseif Exception = -492 then
__errCause__ := concat ("Execute message not implemented ∂"", ^PString(ΔSP^)^, "∂"") # currently no way to execute this from SADE!
ΔSP := ΔSP+4;
elseif Exception = -490 then
__errCause__ := "User Break encountered"
else
__errCause__ := concat('Error number ', Exception)
end
return __errCause__
end
proc StandardEntry
define __errCause__ := GetErrorString();
if __SourceDbg__ then
if addrToSource(ΔPC, __SourceInFront__) and (Exception > 0) then
if Exception <> kSETrace then
if Breakalert then
alert concat(__errCause__, ' at ', where(ΔPC))
elseif (Exception <> kSEprocessLoaded) and (Exception <> kSEAddressBreak) and (Exception <> kSESADEKeyInterrupt) then
alert concat(__errCause__, ' at ', where(ΔPC))
end
end
else
# if we are at the startup code for a C program, move ahead to main.(0)
if (Exception = kSEprocessLoaded) and (eval('main.(0)', '????') <> '????') then
if (__StopBeforeStatic__ = 0) then
go til main.(0)
stop
else
printf "\n%s at %t\n", __errCause__, where(ΔPC)
stop
end
else
open WorksheetWindow
redirect append concat(WorksheetWindow, '.§')
printf "\n%t in ""%t""\n", __errCause__, ^Δpstring(@ΔCurApName)^
disasm ΔPC 1
redirect pop
end
end
else # Assembly mode
if Exception <> kSETrace then
printf "\n%t in ""%t""\n", __errCause__, ^Δpstring(@ΔCurApName)^
end
disasm ΔPC 1
end
if __NumWatchVars__ > 0 then
DisplayWatchVars
end
if __WantStackWindow__ > 0 then
redirect concat(SADEDir, "Stack")
DoStack
redirect pop
end
if __WantRegisterWindow__ > 0 then
redirect concat(SADEDir, "Registers")
Registers
redirect pop
end
end
OnEntry StandardEntry
#
#
# Killing or untargeting the target
# Killing a target means to terminate it. Untargeting it, however, simply means for
# SADE to stop treating it as a target. The semantics of untargeting are as follows:
# if the target is running, it is left running. If it is suspended at a breakpoint,
# it is restarted. If it is suspended due to a "hard" exception (e.g. a bus error),
# it is killed.
# Care is required in killing MPW tools. Since in debugging a tool SADE's target is
# actually the MPW shell, the kill command will kill the shell as well as the tool.
# To avoid this, the KillTool proc below will kill a suspended tool without killing
# the shell. (KillTool won't kill a running tool.) The KillTarget proc checks the
# type of the target and executes either Kill or KillTool as appropriate.
#
proc UnTarget
Target ''
end
proc KillTool
ΔPC := @µSYSRECOVER # set the pc to the shell's error recovery routine
go
end
proc KillTarget
if TargetIsMPWTool then
KillTool
else
kill
end
end
#
# Macsbug equivalent command names for SADE
# if you want these, remove the leading comments.
# NOTE that these macros will be found before any program variables
# of the same name!
#
# macro g "go"
# macro il "disasm"
# macro ip "disasm ΔPC-20 40"
# macro br "break"
# macro ht "heap totals"
# macro hd "heap display"
# macro atba "break all traps from applzone..applzone^"
# macro mc "macro"
# macro id "disasm"
# macro sc "stack"
# macro td "registers"
#
# Source Breakpoints
#
proc SetSourceBreak
CheckNullTarget
define __sourceBreak__ := sourceToAddr(activeWindow, 1)
if typeof(__sourceBreak__) = 'PString' then
alert concat('Cannot determine break address: ', __sourceBreak__)
else
break __sourceBreak__
if not addrToSource(__sourceBreak__, 1) then # verify statement selection
alert 'Able to set but not display breakpoint; SourcePath may not be set'
end
end
end
proc ProcessBreakIf # used by SetSourceBreakIf below
define __i__, __addr__
for __i__ := 1 to __MaxBreakifs__ do
if (__addr__ := __BreakifAddr__[__i__]) <> 0 then
if __addr__ = ΔPC then
if eval(__BreakifCond__[__i__]) then
stop
end
end
end
end
end
proc SetSourceBreakIf
CheckNullTarget
define __i__, __j__, __condition__, __EvaledCondition__
define __sourceBreak__ := sourceToAddr(activeWindow, 1)
if typeof(__sourceBreak__) = 'PString' then
alert concat('Cannot determine break address: ', __sourceBreak__)
else
if (__condition__ := request('Condition to break on?')) = '_CANCEL_' then
return
elseif __condition__ = '' then
alert 'No condition was specified; break not set'
else
# check for valid condition
__EvaledCondition__ := eval(__condition__, '???')
if typeof(__EvaledCondition__) = 'PString' then
if __EvaledCondition__ = '???' then
if not confirm('Variable not defined in current scope. Still set conditional break?') then
return
end
elseif copy(__EvaledCondition__, 1, 21) = '### Eval syntax error' then
alert concat('Cannot set conditional break. Expression syntax error: ', __condition__)
return
end
end
for __i__ := 1 to __MaxBreakifs__ + 1 do # try to add to conditional break table
if __i__ = (__MaxBreakifs__ + 1) then
if confirm('Conditional break table full; remove previous breaks?') then
for __j__ := 1 to __MaxBreakifs__ do
unbreak __BreakifAddr__[__j__]
__BreakifAddr__[__j__] := 0
end
__BreakifAddr__[1] := __sourceBreak__
__BreakifCond__[1] := __condition__
leave
end
return
elseif (__BreakifAddr__[__i__] = 0) | (__sourceBreak__ = __BreakifAddr__[__i__]) then
__BreakifAddr__[__i__] := __sourceBreak__
__BreakifCond__[__i__] := __condition__
leave
end
end
end
break __sourceBreak__ processBreakIf
if not addrToSource(__sourceBreak__, 1) then # verify statement selection
alert 'Able to set but not display breakpoint; SourcePath may not be set'
end
end
end
proc UnSetSourceBreak
CheckNullTarget
define __i__
define __sourceBreak__ := sourceToAddr(activeWindow, 1)
if typeof(__sourceBreak__) = 'PString' then
alert concat('Cannot determine break address: ', __sourceBreak__)
else
unbreak __sourceBreak__
for __i__ := 1 to __MaxBreakifs__ do # remove from Breakif table if present
if __sourceBreak__ = __BreakifAddr__[__i__] then
__BreakifAddr__[__i__] := 0
leave
end
end
if addrToSource(__sourceBreak__, 1) then; end # verify statement selection
end
end
proc StepMenu
CheckNullOrRunningTarget
if __SourceDbg__ = 0 then
step asm
else
step
end
end
proc StepIntoMenu
CheckNullOrRunningTarget
if __SourceDbg__ = 0 then
step asm into
else
step into
end
end
proc StepOut
CheckNullOrRunningTarget
if PCIsAtLinkA6 then # we are looking at a LINK instruction- A6 has not been set up
go til (ΔA7)^ # but ΔA7 probably contains the right value
else # a LINK has already taken place
go til (ΔA6+4)^
end
end
proc GoTil
CheckNullOrRunningTarget
define __sourceBreak__ := sourceToAddr(activeWindow, 1)
if typeof(__sourceBreak__) = 'PString' then
alert concat('Cannot determine break address: ', __sourceBreak__)
else
go til __sourceBreak__
end
end
proc InWhatStatement
CheckNullOrRunningTarget
if NOT addrToSource(ΔPC, __SourceInFront__) then
alert "Cannot find source for PC."
end
end
proc ShowWhere
define __loc__
CheckNullTarget
__loc__ := sourceToAddr(ActiveWindow, 1)
if typeof(__loc__) = 'PString' then
alert concat('Cannot determine address from source: ', __loc__)
else
alert concat('At ', where(__loc__))
end
end
proc ShowSource(__theSelection__)
CheckNullTarget
define __theFunc__ := eval(__theSelection__, '???')
if typeof(__theFunc__) = 'PString' then
if __theFunc__ = '???' then
alert concat('"', __theSelection__, '" is not a function or procedure name which is known at this point.')
else
alert concat('"', __theSelection__, '" is not a function or procedure name.')
end
abort
end
if typeof(__theFunc__) <> 'CodeModule' then
alert concat('"', __theSelection__, '" is not a function or procedure.')
elseif not addrToSource(__theFunc__, 1) then
alert concat('The source for "', __theSelection__, '" could not be found.')
end
end
proc ToggleSourceDbg
if __SourceDbg__ = 0 then
__SourceDbg__ := 1
deletemenu 'SourceCmds' '!Asm [vs. Source] Debugging' # '' is control-r (a checkmark)
addmenu 'SourceCmds' '!Source [vs. Asm] Debugging' 'ToggleSourceDbg' # '' is control-r (a checkmark)
else
__SourceDbg__ := 0
deletemenu 'SourceCmds' '!Source [vs. Asm] Debugging' # '' is control-r (a checkmark)
addmenu 'SourceCmds' '!Asm [vs. Source] Debugging' 'ToggleSourceDbg' # '' is control-r (a checkmark)
end
end
proc ShowValue(__theSelection__)
CheckNullTarget
open concat(SADEDir, "Values")
redirect append concat(SADEDir, "Values")
CheckValidLocalVars
PrettyPrintValue(__theSelection__)
redirect pop
end
proc ShowValueInHex(__theSelection__)
CheckNullTarget
open concat(SADEDir, "Values")
redirect append concat(SADEDir, "Values")
CheckValidLocalVars
PrettyPrintValueInHex(__theSelection__)
redirect pop
end
proc __CheckPointer__(__theSelection__)
define __ErrorMessage__
define __EvaledPointer__ := eval(__theSelection__, '????')
if typeof(__EvaledPointer__) = 'PString' then
if __EvaledPointer__ = '????' then
__ErrorMessage__ := ": Undefined"
elseif copy(__EvaledPointer__, 1, 21) = '### Eval syntax error' then
__ErrorMessage__ := ": Syntax Error"
end
__ErrorMessage__ := concat(__theSelection__, __ErrorMessage__)
__Fail__(__ErrorMessage__)
end
if sizeof(__EvaledPointer__) <> 4 then
__Fail__(concat(__theSelection__, " is not a pointer."))
end
if eval(__theSelection__) = 0 then
__ErrorMessage__ := concat(concat("Cannot dereference ", __theSelection__), ' = 0')
__Fail__(__ErrorMessage__)
end
end
proc ShowDereferencedValue(__theSelection__)
CheckNullTarget
__theSelection__ := BackquotedSelection(__theSelection__)
__CheckPointer__(__theSelection__)
ShowValue(concat(__theSelection__, '^'))
end
proc ShowDereferencedValueInHex(__theSelection__)
CheckNullTarget
__theSelection__ := BackquotedSelection(__theSelection__)
__CheckPointer__(__theSelection__)
ShowValueInHex(concat(__theSelection__, '^'))
end
proc AddWatchVar(__theSelection__)
CheckNullTarget
define __EvaluedExpr__
if __NumWatchVars__ >= __MaxWatchVars__ then
alert "Cannot add more watch variables"
else
__theSelection__ := BackquotedSelection(__theSelection__)
__EvaluedExpr__ := Eval(__theSelection__, '???')
if typeof(__EvaluedExpr__) = 'PString' then
if copy(__EvaluedExpr__, 1, 21) = '### Eval syntax error' then
alert concat('Cannot add watch variable. Expression syntax error: ', __theSelection__)
return
elseif __EvaluedExpr__ = '???' then
if not confirm(concat(__theSelection__, ' not defined at this time. Still add as watch variable?')) then
return
end
end
end
__NumWatchVars__ := __NumWatchVars__ + 1
__WatchVar__[__NumWatchVars__] := __theSelection__
# Now refresh the display window
DisplayWatchVars
end
end
proc DeleteWatchVar(__theSelection__)
CheckNullTarget
define __i__, __found__ := 0
__theSelection__ := BackquotedSelection(__theSelection__)
for __i__ := 1 to __NumWatchVars__ do
if __found__ then
__WatchVar__[__i__-1] := __WatchVar__[__i__]
elseif __theSelection__ = __WatchVar__[__i__] then
__found__ := 1
end
end
if __found__ then
__WatchVar__[__NumWatchVars__] := 0
__NumWatchVars__ := __NumWatchVars__ - 1
# Now refresh the display window
DisplayWatchVars
else
alert concat('Cannot find watch variable "', __theSelection__, '" to delete')
end
end
proc DeleteAllWatchVars
CheckNullTarget
__NumWatchVars__ := 0
open behind concat(SADEDir, "Variable Watch") # These two lines erase window
redirect concat(SADEDir, "Variable Watch")
redirect pop
end
proc SADEHelp(__theSelection__) # contributed by Bob E., DSG. Thanks Bob.
redirect concat(SADEDir, "SADE_Info")
printf "# Select a word and then choose the SADE Help menu item.\n"
printf "# try: BuiltIns Commands Expressions Patterns\n"
printf "# : Shortcuts Variables Basetypes <commandName>\n\n"
#
if __theSelection__ = '' then
__theSelection__ := "Commands"
end
help expr(__theSelection__)
redirect pop
open concat(SADEDir, "SADE_Info")
define __dummy__
__dummy__ := selection(concat(SADEDir, "SADE_Info"), 0, 0)
end
#
#
# SADE menu initialization
# Sets up SourceCmds and Variables menus, and adds Kill, Quit, and Help items
# to the File menu.
#
#
addmenu 'File' 'Stop Before Constructor' 'ToggleStopBeforeStatic'
# You can use the commented-out form if you would like a cmd-K equivalent
# for the Kill menu item.
#addMenu 'File' '(Kill /K' 'KillTarget'
addMenu 'File' '(Kill' 'KillTarget'
addMenu 'File' '(-' ''
# The quit command asks you for each dirty file whether to save before quitting.
# SaveAllAndQuit saves all files before quitting. Use the commented-out form if
# you'd rather be prompted than save automatically.
proc SaveAllAndQuit
save all
quit
end
#addMenu 'File' 'Quit /Q' 'quit'
addMenu 'File' 'Quit /Q' 'SaveAllAndQuit'
addMenu 'Find' '(-' ''
addMenu 'Find' 'SADE Help/1' 'SADEHelp(selection(ActiveWindow))'
addmenu 'SourceCmds' 'Break /B' 'SetSourceBreak'
addmenu 'SourceCmds' 'Break if…/∫' 'SetSourceBreakIf'
addmenu 'SourceCmds' 'Unbreak /U' 'UnSetSourceBreak'
addmenu 'SourceCmds' 'Unbreak All' 'unbreak all'
addmenu 'SourceCmds' '(-' ''
addmenu 'SourceCmds' 'Step /L' 'StepMenu'
addmenu 'SourceCmds' 'Step Into /¬' 'StepIntoMenu' # '¬' is Opt-l
addmenu 'SourceCmds' 'Step Out' 'StepOut'
addmenu 'SourceCmds' '(-' ''
addmenu 'SourceCmds' 'Go /P' 'go'
addmenu 'SourceCmds' 'Go Til /π' 'GoTil'
addmenu 'SourceCmds' '(-' ''
addMenu 'SourceCmds' 'In What Statement? /I' 'InWhatStatement'
addMenu 'SourceCmds' 'Statement Selected Is?' 'ShowWhere'
addMenu 'SourceCmds' 'Show Selected Routine' 'ShowSource(selection(ActiveWindow))'
addmenu 'SourceCmds' '(-' ''
addmenu 'SourceCmds' 'Break if No Source' 'ToggleBreakifNoSource'
addmenu 'SourceCmds' '!Source [vs. Asm] Debugging' 'ToggleSourceDbg' # '' is control-r (a checkmark)
addmenu 'Variables' 'Show Value /√' 'ShowValue(selection(ActiveWindow))' # '√' is Opt-v
addmenu 'Variables' 'Show Dereferenced Value /◊' 'ShowDereferencedValue(selection(ActiveWindow))' # '◊' is Opt-shift-v
addmenu 'Variables' 'Show Value in Hex' 'ShowValueInHex(selection(ActiveWindow))'
addmenu 'Variables' 'Show Dereferenced Value in Hex' 'ShowDereferencedValueInHex(selection(ActiveWindow))'
addmenu 'Variables' '(-' ''
addmenu 'Variables' 'Add Watch Variable' 'AddWatchVar(selection(ActiveWindow))'
addmenu 'Variables' 'Delete Watch Variable' 'DeleteWatchVar(selection(ActiveWindow))'
addmenu 'Variables' 'Delete All Watch Variables' 'DeleteAllWatchVars'
addmenu 'Variables' '(-' ''
addmenu 'Variables' 'Show Registers' 'DisplayRegs'
addmenu 'Variables' 'Live Register Window' 'ToggleWantRegisterWindow'
addmenu 'Variables' '(-' ''
addmenu 'Variables' 'Show Stack' 'DisplayStack'
addmenu 'Variables' 'Live Stack Window' 'ToggleWantStackWindow'
#
# Execute SADEUserStartup, where you can add to and modify the stuff supplied here.
#
execute ':SADEUserStartup'